/*******************************************************************************
* Copyright (c) 2009, 2017 Remy Chi Jian Suen and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Remy Chi Jian Suen <remy.suen@gmail.com> - initial API and implementation
* Jeanderson Candido <http://jeandersonbc.github.io> - Bug 433608
******************************************************************************/
package org.eclipse.jface.tests.wizards;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Layout;
import junit.framework.TestCase;
public class WizardProgressMonitorTest extends TestCase {
private ProgressMonitoringWizardDialog dialog;
@Override
protected void setUp() throws Exception {
super.setUp();
// initialize a display
Display.getDefault();
dialog = new ProgressMonitoringWizardDialog(new TheTestWizard());
dialog.setBlockOnOpen(false);
}
@Override
protected void tearDown() throws Exception {
if (dialog != null) {
dialog.close();
}
dialog = null;
super.tearDown();
}
/**
* This test ensures that the labels of a progress monitor are cleared
* in-between calls to the wizard dialog's run(boolean, boolean,
* IRunnableWithProgress) method. If they are not cleared in between runs,
* they end up spilling over to the successive call and causes flickering of
* text in the label.
*/
public void testProgressLabelsClearedBug271530() throws Exception {
// make up some random task names
final String[] taskNames = { "Task A", "Task B" }; //$NON-NLS-1$ //$NON-NLS-2$
// normal "stop button" behavior
dialog.useStopButton = true;
// open the dialog
dialog.open();
// run task A, we don't fork so we can make a UI call within the
// runnable
dialog.run(false, true, getRunnable(taskNames[0]));
performAsserts();
// run task B now, again, we don't fork so we can make a UI call within
// the runnable
dialog.run(false, true, getRunnable(taskNames[1]));
// check that the label has been cleared
performAsserts();
}
protected void performAsserts() {
assertEquals("The progress monitor's label should have been cleared", //$NON-NLS-1$
"", dialog.getProgressMonitorLabelText()); //$NON-NLS-1$
String subTask = dialog.getProgressMonitorSubTaskText();
if(subTask !=null && subTask.length() != 0)
{
fail("The progress monitor's subtask should have been cleared"); //$NON-NLS-1$
}
}
protected IRunnableWithProgress getRunnable(final String taskName) {
return monitor -> {
// check that the label is empty
assertEquals("The progress monitor's label is not initially empty", //$NON-NLS-1$
"", dialog.getProgressMonitorLabelText()); //$NON-NLS-1$
// check the subtask as well
String subTask = dialog.getProgressMonitorSubTaskText();
if (subTask != null && subTask.length() != 0) {
fail("The progress monitor's subtask is not initially empty"); //$NON-NLS-1$
}
monitor.beginTask(taskName, 1);
monitor.subTask("some sub task"); //$NON-NLS-1$
};
}
/**
* A wizard dialog that leverages ProgressMonitorPartSubclass to expose the
* progress monitor's label text.
*/
class ProgressMonitoringWizardDialog extends WizardDialog {
boolean useStopButton;
ProgressMonitoringWizardDialog(IWizard newWizard) {
super(null, newWizard);
}
@Override
protected ProgressMonitorPart createProgressMonitorPart(
Composite composite, GridLayout pmlayout) {
return new ProgressMonitorPartSubclass(composite, pmlayout, useStopButton);
}
public String getProgressMonitorLabelText() {
ProgressMonitorPartSubclass monitor = (ProgressMonitorPartSubclass) getProgressMonitor();
return monitor.getLabelText();
}
public String getProgressMonitorSubTaskText() {
ProgressMonitorPartSubclass monitor = (ProgressMonitorPartSubclass) getProgressMonitor();
return monitor.getSubTaskText();
}
}
/**
* A special subclass of the ProgressMonitorPart that exposes this monitor's
* label's text.
*/
class ProgressMonitorPartSubclass extends ProgressMonitorPart {
ProgressMonitorPartSubclass(Composite parent, Layout layout, boolean useStopButton) {
super(parent, layout, useStopButton);
}
public String getLabelText() {
return fLabel.getText();
}
public String getSubTaskText() {
return fSubTaskName;
}
}
/**
* This test ensures that a wizard dialog subclass which overrides the
* #getProgressMonitorPart method and returns a monitor without the stop button
* will fail gracefully. That is, the runnable will run as expected.
* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=287887#c57
*/
public void testProgressMonitorWithoutStopButtonBug287887() throws Exception {
// make up some random task names
final String[] taskNames = { "Task A", "Task B" }; //$NON-NLS-1$ //$NON-NLS-2$
// no stop button, this is an invalid configuration
dialog.useStopButton = false;
// open the dialog
dialog.open();
// run task A, we don't fork so we can make a UI call within the
// runnable
dialog.run(false, true, getRunnable(taskNames[0]));
performAsserts();
// run task B now, again, we don't fork so we can make a UI call within
// the runnable
dialog.run(false, true, getRunnable(taskNames[1]));
// check that the label has been cleared
performAsserts();
// we are successful simply by getting here without exception
}
}